package com.ithiema.reggie.filter;

import com.alibaba.druid.sql.parser.Lexer;
import com.alibaba.fastjson.JSON;
import com.ithiema.reggie.common.BaseContext;
import com.ithiema.reggie.common.GlobalConstant;
import com.ithiema.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.support.ResourcePropertiesPersister;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 过滤器 指定拦截请求
 *  /user/sendMsg  发送验证码
 *  /user/login 用户登录
 * @author wangxiao
 * @since 2022/11/1 10:16
 */
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
    //    未登录的提示信息
    private static final String NOT_LOGIN = "NOTLOGIN";//和前端响应的值要一致就可以
    //    放行的路径
    private static final String[] URLS = new String[]{
            "/employee/login", "/employee/logout", "/backend/**", "/front/**","/common/**",
            "/user/sendMsg","/user/login","/doc.html",
            "/webjars/**",
            "/swagger-resources",
            "/v2/api-docs"
    };

    //    路径匹配器，
    private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();

    /**
     * 所有指定的请求都会到达这里，
     * 过滤器，在吹完义务逻辑之后，还是需要放行的
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("已到达过滤器");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
//        1.获取本次请求的URL
        String requestURL = request.getRequestURI();//从request域中获取请求地址
//         判断本次请求是否需要校验用户登录状态，不需要处理则直接放行
        for (String url : URLS) {
            // 放行鉴权就是在做请求路径的匹配,如果要是符合我们在数组中定义的请求路径的话,就会放行
            // 如果要是不匹配的话,就会走鉴权操作
            // 这个匹配,实际上就是在做字符串对比. 对比的就是请求路径,以及我们在数据中定义的路径
            // 匹配操作,匹配成功会返回true
            // 第一次参数是匹配的路径,第二个参数请求路径
            boolean match = ANT_PATH_MATCHER.match(url, requestURL);
//        如果匹配成功
            if (match) {
//                放行操作
                filterChain.doFilter(request, response);
                return;
            }
        }
        // 4、判断登录状态，如果已登录，则直接放行
        // key是employee
        Long currentUserId = (Long) request.getSession().getAttribute(GlobalConstant.EMPLOYEE_ID);
        request.getSession().getAttribute(GlobalConstant.EMPLOYEE_ID);
//        如果不是空，就代表已经登陆
        if (currentUserId != null){
//            已登陆，则放行
            Long threadId = Thread.currentThread().getId();
            log.info("过滤器====当前执行线程ID ===> {}",threadId);
//            存入threadLocal
            BaseContext.setCurrentUserId(currentUserId);
            filterChain.doFilter(request,response);
            return;
        }

        // 兼容移动端用户

        Long mobileId = (Long) request.getSession().getAttribute(GlobalConstant.MOBILE_ID);
//        如果不是空，就代表已经登陆
        if (mobileId != null){
//            已登陆，则放行
            Long threadId = Thread.currentThread().getId();
            log.info("过滤器====当前执行线程ID ===> {}",threadId);
//            存入threadLocal  写入得id也是移动端得id
            BaseContext.setCurrentUserId(mobileId);
            filterChain.doFilter(request,response);
            return;
        }



//      如果未登录则返回未登录结果
        R<String> notLogin = R.error(NOT_LOGIN);
        response.getWriter().write(JSON.toJSONString(notLogin));

    }
}
